﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using RecipeProject.DataAccess;
using System.Windows.Input;

namespace RecipeProject.ViewModel
{
    /// <summary>
    /// Represents a container of RecipeVM objects
    /// that has support for staying synchronized with the
    /// RecipeDatabase.  This class also provides information
    /// related to multiple selected Recipes.
    /// </summary>
    class AllRecipesVM : WorkspaceVM
    {
        #region Fields

        readonly RecipeDatabase _RecipeRepository;
        readonly MainWindowVM _parent;
        RecipeVM _selectedRecipe;

        #endregion // Fields

        #region Constructor

        public AllRecipesVM(MainWindowVM parent, RecipeDatabase RecipeRepository)
        {
            if (parent == null)
                throw new ArgumentNullException("parent");
            if (RecipeRepository == null)
                throw new ArgumentNullException("RecipeRepository");

            base.DisplayName = "Browse Recipes";

            _parent = parent;

            _RecipeRepository = RecipeRepository;

            // Subscribe for notifications of when a new r is saved.
            _RecipeRepository.RecipeAdded += this.OnRecipeAddedToRepository;

            // Populate the AllRecipes collection with RecipeViewModels.
            this.CreateAllRecipes();              
        }

        void CreateAllRecipes()
        {
            List<RecipeVM> all =
                (from r in _RecipeRepository.GetRecipes()
                 select new RecipeVM(r, _RecipeRepository)).ToList();

            this.AllRecipes = new ObservableCollection<RecipeVM>(all);
        }

        #endregion // Constructor

        #region Public Interface

        /// <summary>
        /// Returns a collection of all the RecipeVM objects.
        /// </summary>
        public ObservableCollection<RecipeVM> AllRecipes { get; private set; }

        public RecipeVM SelectedRecipe 
        {
            get { return _selectedRecipe; }
            set
            {
                if (_selectedRecipe == value)
                    return;
                _selectedRecipe = value;
                OnPropertyChanged("SelectedRecipe");
                OnPropertyChanged("RecipeSelected");
            }
        }

        public bool RecipeSelected { get { return SelectedRecipe != null; } }

        public ICommand ViewRecipe { get { return new RelayCommand(recipeVM => _parent.RequestNewWorkspace((WorkspaceVM)recipeVM)); } }

        #endregion // Public Interface

        #region  Base Class Overrides

        protected override void OnDispose()
        {
            foreach (RecipeVM custVM in this.AllRecipes)
                custVM.Dispose();

            this.AllRecipes.Clear();

            _RecipeRepository.RecipeAdded -= this.OnRecipeAddedToRepository;
        }

        #endregion // Base Class Overrides

        #region Event Handling Methods

        void OnRecipeAddedToRepository(object sender, RecipeAddedEventArgs e)
        {
            var viewModel = new RecipeVM(e.NewRecipe, _RecipeRepository);
            this.AllRecipes.Add(viewModel);
        }

        #endregion // Event Handling Methods
    }
}